package com.jzo2o.health.service.impl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.read.listener.PageReadListener;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.common.expcetions.DBException;
import com.jzo2o.common.utils.BeanUtils;
import com.jzo2o.common.utils.DateUtils;
import com.jzo2o.common.utils.JsonUtils;
import com.jzo2o.health.mapper.ReservationSettingMapper;
import com.jzo2o.health.model.domain.ReservationSetting;
import com.jzo2o.health.model.dto.request.ReservationSettingUpsertReqDTO;
import com.jzo2o.health.model.dto.response.ReservationDateResDTO;
import com.jzo2o.health.model.dto.response.ReservationSettingResDTO;
import com.jzo2o.health.model.excel.ReservationImportData;
import com.jzo2o.health.service.IReservationSettingService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * 预约设置 服务实现类
 * </p>
 *
 * @author WangXinyi
 * @since 2024-12-13
 */
@Service
@Slf4j
public class ReservationSettingServiceImpl extends ServiceImpl<ReservationSettingMapper, ReservationSetting> implements IReservationSettingService {



    @Autowired
    private ReservationSettingMapper reservationSettingMapper;
    /**
     * 按月查询预约设置
     *
     * @param date
     * @return
     */
    @Override
    public List<ReservationSettingResDTO> getReservationSettingByMonth(String date) {
        // 定义与日期字符串格式相匹配的 DateTimeFormatter
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-M");
        //获取年份和月份
        YearMonth yearMonth = YearMonth.parse(date, formatter);
        //获取该月的第一天和最后一天
        LocalDate atedDay = yearMonth.atDay(1);
        LocalDate atedEndOfMonth = yearMonth.atEndOfMonth();
        //查询数据库
        List<ReservationSettingResDTO> reservationSettingResDTOList = new ArrayList<>();
        List<ReservationSetting> list = lambdaQuery().between(ReservationSetting::getOrderDate, atedDay, atedEndOfMonth).list();
        for (ReservationSetting reservationSetting : list) {
            ReservationSettingResDTO reservationSettingResDTO = ReservationSettingResDTO.builder().reservations(reservationSetting.getReservations())
                    .date(reservationSetting.getOrderDate().toString())
                    .number(reservationSetting.getNumber())
                    .build();
            reservationSettingResDTOList.add(reservationSettingResDTO);
        }
        return reservationSettingResDTOList;
    }

    /**
     * 编辑预约设置
     */
    @Override
    public void editNumberByDate(ReservationSettingUpsertReqDTO reservationSettingUpsertReqDTO) {
        Integer number = reservationSettingUpsertReqDTO.getNumber(); //预约人数
        LocalDate orderDate = reservationSettingUpsertReqDTO.getOrderDate(); //预约日期
        //先根据日期查询数据是否为空
        ReservationSetting reservationSetting = lambdaQuery().eq(ReservationSetting::getOrderDate, orderDate).one();
        if (reservationSetting == null) {
            //插入数据
            ReservationSetting reservationSetting1 = BeanUtils.copyBean(reservationSettingUpsertReqDTO, ReservationSetting.class);
            reservationSetting1.setReservations(0);//已预约人数默认0
            boolean result = save(reservationSetting1);
            if (!result) {
                throw new DBException("编辑预约设置失败");
            }
        } else {
            //已有数据，编辑
            boolean update = lambdaUpdate().eq(ReservationSetting::getOrderDate, orderDate)
                    .set(ReservationSetting::getNumber, number)
                    .update();
            if (!update) {
                throw new DBException("编辑预约设置失败");
            }
        }
    }


    /**
     * 管理端批量预约设置
     */
    @Override
    public void upload(MultipartFile file) {
        InputStream inputStream = null;
        try {
            inputStream = file.getInputStream();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // 这里 需要指定读用哪个class去读，然后读取第一个sheet 文件流会自动关闭
        // 这里默认每次会读取100条数据 然后返回过来 直接调用使用数据就行
        // 具体需要返回多少行可以在`PageReadListener`的构造函数设置
        EasyExcel.read(inputStream, ReservationImportData.class, new PageReadListener<ReservationImportData>(dataList -> {
            for (ReservationImportData data : dataList) {
                log.info("读取到一条数据{}", JsonUtils.toJsonStr(data));

                ReservationSetting reservationSetting1 = lambdaQuery().eq(ReservationSetting::getOrderDate, DateUtils.parseDate(data.getDate(), "yyyy-MM-dd")).one();
                if (reservationSetting1 != null) {
                    //查询数据库，如果存在则修改
                    boolean update = lambdaUpdate().eq(ReservationSetting::getOrderDate, data.getDate())
                            .set(ReservationSetting::getReservations, 0)
                            .set(ReservationSetting::getNumber, data.getNumber())
                            .update();
                    if (!update){
                        throw new DBException("修改数据库失败");
                    }
                } else {
                    //没有则添加
                    ReservationSetting reservationSetting = new ReservationSetting();
                    reservationSetting.setNumber(data.getNumber());
                    reservationSetting.setReservations(0);
                    reservationSetting.setOrderDate(DateUtils.parseDate(data.getDate(), "yyyy-MM-dd"));
                    boolean result = save(reservationSetting);
                    if (!result) {
                        throw new DBException("添加数据库失败");
                    }
                }
            }
        })).sheet().doRead();
    }


    /**
     * 用户端预约设置查询
     *
     * @param month
     * @return
     */
    @Override
    public ReservationDateResDTO getReservationDateByMonth(String month) {
        // 定义与日期字符串格式相匹配的 DateTimeFormatter
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-M");
        //获取年份和月份
        YearMonth yearMonth = YearMonth.parse(month, formatter);
        //获取该月的第一天和最后一天
        LocalDate atedDay = yearMonth.atDay(1);
        LocalDate atedEndOfMonth = yearMonth.atEndOfMonth();
        //查询数据库
        List<String> dateList = new ArrayList<>();
        List<ReservationSetting> list = lambdaQuery().between(ReservationSetting::getOrderDate, atedDay, atedEndOfMonth).list();
        for (ReservationSetting reservationSetting : list) {
            //判断可预约人数是否大于预约人数
            //  if (reservationSetting.getNumber() > reservationSetting.getReservations()) {
            dateList.add(reservationSetting.getOrderDate().toString());
            //   }
        }
        return new ReservationDateResDTO(dateList);
    }


    @Override
    public void updateReservations(LocalDate reservationDate) {
        reservationSettingMapper.updateReservations(reservationDate);
    }


    /**
     * 【取消订单模块】取消订单，预约人数-1
     * @param reservationDate
     */
    @Override
    public void substract(LocalDate reservationDate) {
        reservationSettingMapper.substract(reservationDate);
    }
}
